package com.fenrirtec.aepp.common.service.impl;

import java.sql.Connection;
import java.sql.SQLException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fenrirtec.aepp.common.dao.AttachmentDao;
import com.fenrirtec.aepp.common.dao.impl.AttachmentDao_JDBCImpl;
import com.fenrirtec.aepp.common.dto.AttachmentDto;
import com.fenrirtec.aepp.common.dto.UploadDto;
import com.fenrirtec.aepp.common.model.Attachment;
import com.fenrirtec.aepp.common.model.Upload;
import com.fenrirtec.aepp.common.service.AttachmentService;
import com.fenrirtec.core.database.DatabaseSessionManager;
import com.fenrirtec.core.exception.DatabaseException;
import com.fenrirtec.core.exception.UnexpectedException;
import com.fenrirtec.core.utils.BeanCopierUtils;

public class AttachmentServiceImpl implements AttachmentService {
	
	private static final Logger logger = LoggerFactory.getLogger(AttachmentServiceImpl.class);

	@Override
	public Integer saveAttachment(Integer fileType, String path, String comment, String uploadUser) {
		if (logger.isInfoEnabled()) {
			logger.info("[AttachmentServiceImpl#saveAttachment] start.");
		}
		
		DatabaseSessionManager sessionManager = DatabaseSessionManager.getInstance();
		sessionManager.open();
		Connection connection = sessionManager.getSession();
		Integer attachmentId = null;
		
		try {
			connection.setAutoCommit(false);
			AttachmentDao attachmentDao = new AttachmentDao_JDBCImpl();
			attachmentId = attachmentDao.saveAttachment(fileType, path, comment, uploadUser);
			connection.commit();
		} catch (DatabaseException e) {
			// expected
			if (logger.isErrorEnabled()) {
				logger.error("[AttachmentServiceImpl#saveAttachment] database error occurred.", e);
			}
			try {
				connection.rollback();
			} catch (SQLException e1) {
			}
			throw e;
		} catch (Exception e) {
			// unexpected
			if (logger.isErrorEnabled()) {
				logger.error("[AttachmentServiceImpl#saveAttachment] unexpected error occurred.", e);
			}
			try {
				connection.rollback();
			} catch (SQLException e1) {
			}
			throw new UnexpectedException("unexpected error.", e);
		} finally {
			if (logger.isInfoEnabled()) {
				logger.info("[AttachmentServiceImpl#saveAttachment] finish.");
			}
			sessionManager.close();
		}
		return attachmentId;
	}

	@Override
	public AttachmentDto searchAttachment(Integer attachmentId) {
		if (logger.isInfoEnabled()) {
			logger.info("[AttachmentServiceImpl#searchAttachment] start.");
		}
		
		DatabaseSessionManager sessionManager = DatabaseSessionManager.getInstance();
		sessionManager.open();
		Connection connection = sessionManager.getSession();
		Attachment attachment = null;
		
		try {
			connection.setAutoCommit(false);
			AttachmentDao attachmentDao = new AttachmentDao_JDBCImpl();
			attachment = attachmentDao.searchAttachment(attachmentId);
			connection.commit();
		} catch (DatabaseException e) {
			// expected
			if (logger.isErrorEnabled()) {
				logger.error("[AttachmentServiceImpl#searchAttachment] database error occurred.", e);
			}
			try {
				connection.rollback();
			} catch (SQLException e1) {
			}
			throw e;
		} catch (Exception e) {
			// unexpected
			if (logger.isErrorEnabled()) {
				logger.error("[AttachmentServiceImpl#searchAttachment] unexpected error occurred.", e);
			}
			try {
				connection.rollback();
			} catch (SQLException e1) {
			}
			throw new UnexpectedException("unexpected error.", e);
		} finally {
			if (logger.isInfoEnabled()) {
				logger.info("[AttachmentServiceImpl#searchAttachment] finish.");
			}
			sessionManager.close();
		}
		
		AttachmentDto attachmentDto = null;
		if (attachment != null) {
			attachmentDto = new AttachmentDto();
			BeanCopierUtils.copyProperties(attachment, attachmentDto);
		}
		return attachmentDto;
	}

	@Override
	public void relateMemberMaterial(String memberLoginName, String uploadFileCategory, Integer attachmentId) {
		if (logger.isInfoEnabled()) {
			logger.info("[AttachmentServiceImpl#relateMemberMaterial] start.");
		}
		
		DatabaseSessionManager sessionManager = DatabaseSessionManager.getInstance();
		sessionManager.open();
		Connection connection = sessionManager.getSession();
		
		try {
			connection.setAutoCommit(false);
			AttachmentDao attachmentDao = new AttachmentDao_JDBCImpl();
			attachmentDao.relateMemberMaterial(memberLoginName, uploadFileCategory, attachmentId);
			connection.commit();
		} catch (DatabaseException e) {
			// expected
			if (logger.isErrorEnabled()) {
				logger.error("[AttachmentServiceImpl#relateMemberMaterial] database error occurred.", e);
			}
			try {
				connection.rollback();
			} catch (SQLException e1) {
			}
			throw e;
		} catch (Exception e) {
			// unexpected
			if (logger.isErrorEnabled()) {
				logger.error("[AttachmentServiceImpl#relateMemberMaterial] unexpected error occurred.", e);
			}
			try {
				connection.rollback();
			} catch (SQLException e1) {
			}
			throw new UnexpectedException("unexpected error.", e);
		} finally {
			if (logger.isInfoEnabled()) {
				logger.info("[AttachmentServiceImpl#relateMemberMaterial] finish.");
			}
			sessionManager.close();
		}
	}

	@Override
	public void removeAttachment(Integer attachmentId) {
		if (logger.isInfoEnabled()) {
			logger.info("[AttachmentServiceImpl#removeAttachment] start.");
		}
		
		DatabaseSessionManager sessionManager = DatabaseSessionManager.getInstance();
		sessionManager.open();
		Connection connection = sessionManager.getSession();
		
		try {
			connection.setAutoCommit(false);
			AttachmentDao attachmentDao = new AttachmentDao_JDBCImpl();
			attachmentDao.removeAttachment(attachmentId);
			connection.commit();
		} catch (DatabaseException e) {
			// expected
			if (logger.isErrorEnabled()) {
				logger.error("[AttachmentServiceImpl#removeAttachment] database error occurred.", e);
			}
			try {
				connection.rollback();
			} catch (SQLException e1) {
			}
			throw e;
		} catch (Exception e) {
			// unexpected
			if (logger.isErrorEnabled()) {
				logger.error("[AttachmentServiceImpl#removeAttachment] unexpected error occurred.", e);
			}
			try {
				connection.rollback();
			} catch (SQLException e1) {
			}
			throw new UnexpectedException("unexpected error.", e);
		} finally {
			if (logger.isInfoEnabled()) {
				logger.info("[AttachmentServiceImpl#removeAttachment] finish.");
			}
			sessionManager.close();
		}
	}

	@Override
	public Integer upload(String person, Integer personType, String purpose, String path, Integer fileType) {
		if (logger.isInfoEnabled()) {
			logger.info("[AttachmentServiceImpl#upload] start.");
		}
		
		DatabaseSessionManager sessionManager = DatabaseSessionManager.getInstance();
		sessionManager.open();
		Connection connection = sessionManager.getSession();
		Integer uploadId = null;
		
		try {
			connection.setAutoCommit(false);
			AttachmentDao attachmentDao = new AttachmentDao_JDBCImpl();
			uploadId = attachmentDao.upload(person, personType, purpose, path, fileType);
			connection.commit();
		} catch (DatabaseException e) {
			// expected
			if (logger.isErrorEnabled()) {
				logger.error("[AttachmentServiceImpl#upload] database error occurred.", e);
			}
			try {
				connection.rollback();
			} catch (SQLException e1) {
			}
			throw e;
		} catch (Exception e) {
			// unexpected
			if (logger.isErrorEnabled()) {
				logger.error("[AttachmentServiceImpl#upload] unexpected error occurred.", e);
			}
			try {
				connection.rollback();
			} catch (SQLException e1) {
			}
			throw new UnexpectedException("unexpected error.", e);
		} finally {
			if (logger.isInfoEnabled()) {
				logger.info("[AttachmentServiceImpl#upload] finish.");
			}
			sessionManager.close();
		}
		
		return uploadId;
	}

	@Override
	public UploadDto uploadInfo(Integer uploadId) {
		if (logger.isInfoEnabled()) {
			logger.info("[AttachmentServiceImpl#uploadInfo] start.");
		}
		
		DatabaseSessionManager sessionManager = DatabaseSessionManager.getInstance();
		sessionManager.open();
		Connection connection = sessionManager.getSession();
		Upload upload = null;
		
		try {
			connection.setAutoCommit(false);
			AttachmentDao attachmentDao = new AttachmentDao_JDBCImpl();
			upload = attachmentDao.uploadInfo(uploadId);
			connection.commit();
		} catch (DatabaseException e) {
			// expected
			if (logger.isErrorEnabled()) {
				logger.error("[AttachmentServiceImpl#uploadInfo] database error occurred.", e);
			}
			try {
				connection.rollback();
			} catch (SQLException e1) {
			}
			throw e;
		} catch (Exception e) {
			// unexpected
			if (logger.isErrorEnabled()) {
				logger.error("[AttachmentServiceImpl#uploadInfo] unexpected error occurred.", e);
			}
			try {
				connection.rollback();
			} catch (SQLException e1) {
			}
			throw new UnexpectedException("unexpected error.", e);
		} finally {
			if (logger.isInfoEnabled()) {
				logger.info("[AttachmentServiceImpl#uploadInfo] finish.");
			}
			sessionManager.close();
		}
		
		UploadDto uploadDto = new UploadDto();
		BeanCopierUtils.copyProperties(upload, uploadDto);
		return uploadDto;
	}

	@Override
	public void removeUpload(Integer uploadId) {
		if (logger.isInfoEnabled()) {
			logger.info("[AttachmentServiceImpl#removeUpload] start.");
		}
		
		DatabaseSessionManager sessionManager = DatabaseSessionManager.getInstance();
		sessionManager.open();
		Connection connection = sessionManager.getSession();
		
		try {
			connection.setAutoCommit(false);
			AttachmentDao attachmentDao = new AttachmentDao_JDBCImpl();
			attachmentDao.removeUpload(uploadId);
			connection.commit();
		} catch (DatabaseException e) {
			// expected
			if (logger.isErrorEnabled()) {
				logger.error("[AttachmentServiceImpl#removeUpload] database error occurred.", e);
			}
			try {
				connection.rollback();
			} catch (SQLException e1) {
			}
			throw e;
		} catch (Exception e) {
			// unexpected
			if (logger.isErrorEnabled()) {
				logger.error("[AttachmentServiceImpl#removeUpload] unexpected error occurred.", e);
			}
			try {
				connection.rollback();
			} catch (SQLException e1) {
			}
			throw new UnexpectedException("unexpected error.", e);
		} finally {
			if (logger.isInfoEnabled()) {
				logger.info("[AttachmentServiceImpl#removeUpload] finish.");
			}
			sessionManager.close();
		}
	}
}
